package com.af.community.smart.utils

import android.annotation.SuppressLint
import com.alibaba.sdk.android.oss.ClientException
import com.alibaba.sdk.android.oss.common.auth.OSSFederationCredentialProvider
import com.alibaba.sdk.android.oss.common.auth.OSSFederationToken
import com.lzy.okgo.OkGo
import com.lzy.okgo.convert.StringConvert
import org.json.JSONObject

class OSSAuthCredentialsProvider(private var mAuthServerUrl: String = "") :
    OSSFederationCredentialProvider() {

    private var mDecoder: AuthDecoder? = null

    /**
     * set auth server url
     */
    fun setAuthServerUrl(authServerUrl: String) {
        this.mAuthServerUrl = authServerUrl
    }

    /**
     * set response data decoder
     */
    fun setDecoder(decoder: AuthDecoder) {
        this.mDecoder = decoder
    }

    @SuppressLint("CheckResult")
    @Throws(ClientException::class)
    override fun getFederationToken(): OSSFederationToken? {
        val authToken: OSSFederationToken?
        try {
            var authData  = OkGo.post<String>(mAuthServerUrl)
                .converter(StringConvert())
                .adapt()
                .execute()
                .body()

            if (mDecoder != null) {
                authData = mDecoder!!.decode(authData)
            }

            val jsonObj = JSONObject(authData)
            if (jsonObj.has("AccessKeyId")
                && jsonObj.has("AccessKeySecret")
                && jsonObj.has("SecurityToken")
                && jsonObj.has("Expiration")
            ) {
                val ak = jsonObj.getString("AccessKeyId")
                val sk = jsonObj.getString("AccessKeySecret")
                val token = jsonObj.getString("SecurityToken")
                val expiration = jsonObj.getString("Expiration")
                authToken = OSSFederationToken(ak, sk, token, expiration)
            } else {
                val errorCode = jsonObj.getString("ErrorCode")
                val errorMessage = jsonObj.getString("ErrorMessage")
                throw ClientException("ErrorCode: $errorCode| ErrorMessage: $errorMessage")
            }
            return authToken
        } catch (e: Exception) {
            throw ClientException(e)
        }
    }

    interface AuthDecoder {
        fun decode(data: String): String
    }

}
